import type { ComputedRef, Ref } from 'vue'
import type {
  CascaderDiffData,
  CascaderNodeModel,
  NodeLevel,
  SortableEvent,
} from '../types'
// import { uniqBy } from 'lodash-es'
// @ts-ignore
import { Sortable } from 'sortablejs'
import { sortableOptions } from '../config'
import { useCascaderStore } from './useCascaderStore'

export function moveArrayElement(
  arr: CascaderNodeModel[],
  newIndex: number,
  oldIndex: number,
): CascaderNodeModel[] {
  if (
    newIndex < 0
    || newIndex >= arr.length
    || oldIndex < 0
    || oldIndex >= arr.length
  ) {
    // 索引无效，返回原始数组
    return arr
  }
  // 获取要移动的元素
  const element = arr.splice(oldIndex, 1)[0]

  // 将元素插入到新的位置
  arr.splice(newIndex, 0, element)

  return arr
}

export interface UseSortableOptions {
  el: Ref<Element | undefined>
  nodes: Ref<CascaderNodeModel[]>
  current: ComputedRef<{
    region: string
    level: NodeLevel
  }>
}
const { regionsMap, nodesMap, setDiffData } = useCascaderStore()
function setDiffDataEvent(
  evt: SortableEvent,
  options: UseSortableOptions,
  type: 'ADD' | 'SORT',
) {
  const cdnNode = evt.item.dataset.cdnNode
  if (cdnNode && nodesMap.value?.[cdnNode]) {
    if (type === 'ADD') {
      options?.nodes?.value?.splice?.(
        evt.newIndex!,
        0,
        nodesMap.value?.[cdnNode],
      )
      // options?.nodes?.value = uniqBy(options.nodes.value, 'node_id')
    }
    if (type === 'SORT') {
      const res = moveArrayElement(
        options.nodes.value,
        evt.newIndex!,
        evt.oldIndex!,
      )
      // options.nodes.value = uniqBy(res, 'node_id')
      options.nodes.value = res
    }
  }
  const cdnRegion = evt.item.dataset.cdnRegion
  const cdnLevel = evt.item.dataset.cdnLevel

  if (cdnLevel && cdnRegion && regionsMap.value?.[cdnRegion]) {
    const { current } = options
    const diffData: CascaderDiffData = {
      node: cdnNode!,
      to: {
        region: String(current.value.region),
        level: Number(current.value.level) as NodeLevel,
        index: evt.newIndex || 0,
      },
    }
    setDiffData(diffData, evt)
  }
}
export function useSortable(options: UseSortableOptions) {
  function initialSortable() {
    const _SortableEvent = new Sortable(options.el.value, {
      ...sortableOptions,
      // 元素从一个列表拖拽到另一个列表
      onAdd: (evt: SortableEvent) => {
        setDiffDataEvent(evt, options, 'ADD')
      },
      onRemove(evt: SortableEvent) {
        options?.nodes?.value?.splice?.(evt.oldIndex!, 1)
      },
      // 拖拽元素改变位置的时候
      onSort(evt: SortableEvent) {
        const { from, to } = evt
        if (from.dataset?.levelRow === to.dataset?.levelRow) {
          setDiffDataEvent(evt, options, 'SORT')
        }
      },
    })
  }
  onMounted(async () => {
    await nextTick()
    if (options.el.value)
      initialSortable()
  })

  return {}
}
